home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Sample Code / Pascal Sample 3.0B10 / Source / SampleUtilities.p < prev    next >
Encoding:
Text File  |  1993-10-13  |  12.5 KB  |  350 lines  |  [TEXT/MPS ]

  1. (******************************************************************************
  2. *
  3. *    Apple Macintosh Developer Technical Support
  4. *
  5. *    Interfaces for the utility routines
  6. *
  7. *    Program:    Sample 3.0
  8. *    File:        SampleUtilties.p - Pascal implementation
  9. *
  10. *    by:            Matt Deatherage
  11. *
  12. *    Copyright © 1988-1993 Apple Computer, Inc.
  13. *    All rights reserved.
  14. *
  15. *******************************************************************************
  16. * This file contains many utility routines, ones which don't really fit
  17. * in with the rest of the organization but are still useful, necessary
  18. * and proper.  Some of these routines are from Macintosh Technical Notes
  19. * or Inside Macintosh, and others are just useful encapsulations of
  20. * techniques we needed within Sample.
  21. ******************************************************************************)
  22.  
  23. UNIT SampleUtilities;
  24.  
  25. INTERFACE
  26.  
  27. (*******************************************************************************
  28. * Used Units
  29. *******************************************************************************)
  30.  
  31. USES Errors, Resources, Packages, ToolUtils, PrintTraps, AppleTalk, Processes,
  32.      PPCToolbox, EPPC, Notification, AppleEvents, Features;
  33.  
  34. (*******************************************************************************
  35. * Constants
  36. *******************************************************************************)
  37.  
  38. CONST
  39.     kMissingAppNameStr = - 16396;     { 'STR ' with our application name in it }
  40.  
  41.     rActionAlertBase = 5000;         { base resource ID for close/quit Alert }
  42.     kClosing = 1;                    { string to use when closing }
  43.     kQuitting = 2;                     { string to use when quitting }
  44.  
  45.  
  46.     { Buttons in the "Save changes to document?" Alert }
  47.  
  48.     kSave = 1;                        { "Save" }
  49.     kCancel = 2;                    { "Cancel" }
  50.     kDontSave = 3;                    { "Don’t save" }
  51.  
  52.     { Resource IDs for alerts for errors for HandleFileError }
  53.  
  54.     rIOError = 2001;                 { Got an I/O error on a file }
  55.     rFileAlreadyOpen = 2002;         { That file's already open so you 
  56.                                       can't open it again }
  57.     rNoPermission = 2003;             { You don't have permission for that file }
  58.     rSomeWeirdError = 2004;         { An uncommon error happened }
  59.     rDiskWriteProt = 2005;             { the disk is write-protected }
  60.     rFileVersionInconsistent = 2006;{ the internal file version is later than
  61.                                       what we recognize }
  62.     rFileDiskLocked = 2007;            { can't open with write permission }
  63.     rSaveChanges = 2008;             { ask if we should save changes before
  64.                                       closing or quitting }
  65.     rCantWriteFile = 2009;            { Couldn't write the file to disk }
  66.  
  67.     rUntitledStrings = 1003;        { 'STR#' resource with untitled strings }
  68.     kUntitledWithSpaceString = 1;    { "untitled " }
  69.     kUntitledNoSpaceString = 2;        { "untitled" }
  70.  
  71.     { key code constants for the ClassifyKey routine }
  72.  
  73.     kEnterKey = 3;
  74.     kDeleteKey = 8;
  75.     kTabKey = 9;
  76.     kReturnKey = 13;
  77.     kEscapeKey = 27;
  78.     kLeftArrowKey = 28;
  79.     kRightArrowKey = 29;
  80.     kUpArrowKey = 30;
  81.     kDownArrowKey = 31;
  82.     kPeriodKey = 46;
  83.  
  84.     { bit numbers for the flags in ClassifyKey }
  85.     
  86.     kDigitKeyBit = 0;
  87.     kLetterKeyBit = 1;
  88.     kHexDigitKeyBit = 2;
  89.     kEditKeyBit = 3;
  90.     kNonControlKeyBit = 4;
  91.     kCommandKeyBit = 5;
  92.     kCancelKeyBit = 6;
  93.     kAcceptKeyBit = 7;
  94.  
  95.     { Masks for bits in the flags in ClassifyKey }
  96.     
  97.     kDigitKey = 1;
  98.     kLetterKey = 2;
  99.     kHexDigitKey = 4;
  100.     kEditKey = 8;
  101.     kNonControlKey = 16;
  102.     kCommandKey = 32;
  103.     kCancelKey = 64;
  104.     kAcceptKey = 128;
  105.  
  106. (*******************************************************************************
  107. * Types
  108. *******************************************************************************)
  109.  
  110. TYPE
  111.  
  112. (*******************************************************************************
  113. * Types
  114. *
  115. * FileLikeSpec is a record declared the same as an FSSpec, but they're not
  116. * equivalent records, meaning you have to use a little effort to pass
  117. * FileLikeSpec to an FSSpec File Manager routine. This is as it should be,
  118. * because we're using this as a convenient storage facility, not necessarily
  119. * as something created with MakeFSSpec, and it's important to not pass
  120. * hand-made FSSpec records to the File Manager.    This largely comes in
  121. * handy for changing FSSpec records we get from the system into a format we
  122. * can use instead of the other way around.
  123. ********************************************************************************)
  124.  
  125.     FileLikeSpec = RECORD
  126.         vRefNum: INTEGER;
  127.         parID: LONGINT;
  128.         name: Str63;
  129.         END;
  130.     FileLikeSpecPtr = ^FileLikeSpec;
  131.  
  132. (*******************************************************************************
  133. * Global variables maintained by this unit
  134. *******************************************************************************)
  135.  
  136. VAR
  137.     gUntitledWindowCount: LONGINT;     { count of windows we've opened this
  138.                                       session }
  139.  
  140. (*******************************************************************************
  141. * Types -- we declare an EventRecord pointer for efficiency
  142. *******************************************************************************)
  143.  
  144. TYPE
  145.  
  146.     EventRecordPtr = ^EventRecord;
  147.  
  148. (*******************************************************************************
  149. *
  150. * IsDAWindow - returns TRUE if the window passed is a desk accessory window.
  151. *              Only needed for 6.0.7 systems not using MultiFinder.
  152. *
  153. *******************************************************************************)
  154.  
  155. FUNCTION IsDAWindow(window: WindowPtr): BOOLEAN;
  156.  
  157. (*******************************************************************************
  158. *
  159. * IsAppWindow - returns TRUE if the window passed is a window that belongs
  160. *                to our application
  161. *
  162. *******************************************************************************)
  163.  
  164. FUNCTION IsAppWindow(window: WindowPtr): BOOLEAN;
  165.  
  166. (*******************************************************************************
  167. *
  168. * ClassifyKey - returns information about a keystroke
  169. *
  170. * This routine takes an event record and returns a two-byte INTEGER full of
  171. * bit flags (defined above) telling what kind of keypress it was -- an
  172. * editing key, command key, digit key, etc.  Very useful for filter procedures
  173. * in dialogs.
  174. *
  175. *******************************************************************************)
  176.  
  177. FUNCTION ClassifyKey(theEventPtr: EventRecordPtr): INTEGER;
  178.  
  179. (*******************************************************************************
  180. *
  181. * OKToInteract - checks to see if user interaction is allowed
  182. *
  183. * This routine checks AEInteractWithUser to see if it's OK to talk to the user
  184. * about something, and prepares to do user interaction if it is by setting
  185. * the arrow cursor.
  186. *
  187. *******************************************************************************)
  188.  
  189. FUNCTION OKToInteract: BOOLEAN;
  190.  
  191. (*******************************************************************************
  192. *
  193. * MustInteract - requires user interaction
  194. *
  195. * This routine calls AEInteractWithUser with no timeout, never returning until
  196. * it's ok to interact with the user.
  197. *
  198. *******************************************************************************)
  199.  
  200. PROCEDURE MustInteract;
  201.  
  202. (*******************************************************************************
  203. *
  204. * AlertUser - tell the user about something
  205. *
  206. * This routine takes a resource ID of an 'ALRT' resource, and presents the
  207. * user with that Alert, ignoring what Button is pressed.  Handy for telling
  208. * the user things, but not for getting any input back.
  209. *
  210. *******************************************************************************)
  211.  
  212. PROCEDURE AlertUser(alertNum: INTEGER);
  213.  
  214. (*******************************************************************************
  215. *
  216. * AskUser - ask the user about something
  217. *
  218. * This routine takes a resource ID of an 'ALRT' resource, and presents the
  219. * user with that Alert, returning TRUE if the user picked the default button
  220. * (item #1).
  221. *
  222. *******************************************************************************)
  223.  
  224. FUNCTION AskUser(alertNum: INTEGER): BOOLEAN;
  225.  
  226. (*******************************************************************************
  227. *
  228. * DoPromptSave - find out if the user wants to save a file
  229. *
  230. * This routine presents an alert of the form "Save the <application name>
  231. * document <theName> before <closing/quitting>?   Don't Save/cancel/Save".
  232. * The action is either kClosing or kQuitting, and the return value is
  233. * either kSave, kCancel or kDontSave.  This routine calls MustInteract
  234. * because no default answer to this question is really safe.
  235. *
  236. *******************************************************************************)
  237.  
  238. FUNCTION DoPromptSave(theName: Str63; theAction: INTEGER): INTEGER;
  239.  
  240. (*******************************************************************************
  241. *
  242. * HandleFileError - tell the user about file errors
  243. *
  244. * HandleFileError alerts users to common file errors and also gives a generic
  245. * alert for things we weren't actually prepared to handle.  The error is the
  246. * first parameter, and the window we're working with is the second so the
  247. * dialogs can say things like "You can't save the document <windTitle> because
  248. * the disk is write-protected, bozo."  Or maybe slightly more polite.
  249. *
  250. *******************************************************************************)
  251.  
  252. PROCEDURE HandleFileError(myErr: OSErr; windTitle: Str255);
  253.  
  254. (*******************************************************************************
  255. *
  256. * CheckRequiredAEParms - see if we processed an Apple Event correctly
  257. *
  258. * This routine looks for the keyMissingKeywordAttr in an Apple Event record,
  259. * which is only present if we did _not_ process all the required parameters.
  260. * If it's not present, things are fine and it returns noErr.  Otherwise,
  261. * there was a missing parameter and it returns errAEEventNotHandled.
  262. * Note that this is really a pointer to an AppleEvent record -- Pascal passes
  263. * all parameters bigger than four bytes by reference.  I'd make this more
  264. * explicit by using an "AppleEventPtr" type except one isn't defined, and
  265. * defining it here probably isn't that useful.
  266. *
  267. *******************************************************************************)
  268.  
  269. FUNCTION CheckRequiredAEParms(theAppleEvent: AppleEvent): OSErr;
  270.  
  271. (*******************************************************************************
  272. *
  273. * CreateWindowTitle - make a title for a new window
  274. *
  275. * This routine creates a string suitable for window titles such as "untitled",
  276. * "untitled 2", etc. as specified by Macintosh Human Interface Guidelines.
  277. * You pass an existing string and CreateWindowTitle replaces it with your
  278. * new title.
  279. *
  280. *******************************************************************************)
  281.  
  282. PROCEDURE CreateWindowTitle(VAR theString: Str63);
  283.  
  284. (*******************************************************************************
  285. *
  286. * DoCopyResource - copy a resource from one file to another
  287. *
  288. * This routine is from Inside Macintosh: Macintosh Toolbox Essentials.  It
  289. * copies a resource of type theType and ID theID from resource file source
  290. * to resource file dest, returning any error.
  291. *
  292. *******************************************************************************)
  293.  
  294. FUNCTION DoCopyResource(theType: ResType; theID, source, dest: INTEGER): OSErr;
  295.  
  296. (*******************************************************************************
  297. *
  298. * DeviceLoopSim - simulate DeviceLoop when it's not present
  299. *
  300. * This routine is from issue #10 of _develop_, the Apple Technical Journal.
  301. * It's Forrest Tanaka's routine to simulate the DeviceLoop trap for machines
  302. * that have color QuickDraw but not DeviceLoop (in other words, System 6
  303. * machines).
  304. *
  305. *******************************************************************************)
  306.  
  307. PROCEDURE DeviceLoopSim(drawingRgn: RgnHandle; drawingProc: Ptr;
  308.                         userData: LONGINT; flags: LONGINT);
  309.  
  310. (*******************************************************************************
  311. *
  312. * NewPrJobMerge - merge job-specific parameters of two print records
  313. *
  314. * This routine is from Macintosh Technical Note "Fun with PrJobMerge" and
  315. * works around a bug in LaserWriter 7.x that makes the real PrJobMerge
  316. * sometimes damage your original print record.
  317. *
  318. *******************************************************************************)
  319.  
  320. PROCEDURE NewPrJobMerge(hPrintSrc, hPrintDst: THPrint);
  321.  
  322. (*******************************************************************************
  323. *
  324. * GetNextWindow - find the next window in the window list
  325. *
  326. * This routine returns the window immediately below the specified window.
  327. *
  328. *******************************************************************************)
  329.  
  330. FUNCTION GetNextWindow(theWindow: WindowPtr): WindowPtr;
  331.  
  332. (*******************************************************************************
  333. *
  334. * UpdateAllAppWindows - completely draw all of our document windows
  335. *
  336. * UpdateAllAppWindows goes through all windows we have and makes sure that
  337. * none of them have any pending updates.
  338. *
  339. *******************************************************************************)
  340.  
  341. PROCEDURE UpdateAllAppWindows;
  342.  
  343. IMPLEMENTATION
  344.  
  345. {$I SampleUtilities.inc1.p}
  346.  
  347. END.
  348.